<script setup lang="tsx">
import { reactive, ref, unref, nextTick } from 'vue'
import {
  deleteDataApi,
  selectPageApi,
  saveDataApi,
  updateDataApi,
  publishApi
} from '@/api/sysGenPage'
import { selectModelByFormIdApi, getFormOptionsApi } from '@/api/sysGenForm'
import { useTable } from '@/hooks/web/useTable'
import { useI18n } from '@/hooks/web/useI18n'
import { Table, TableColumn } from '@/components/Table'
import { Search } from '@/components/Search'
import { FormSchema } from '@/components/Form'
import { ContentWrap } from '@/components/ContentWrap'
import { Dialog } from '@/components/Dialog'
import { BaseButton } from '@/components/Button'
import { useSearch } from '@/hooks/web/useSearch'
import { useRouter } from 'vue-router'
import { getMenuListApi } from '@/api/menu'
import { getRoleListApi } from '@/api/role'
import { useValidator } from '@/hooks/web/useValidator'
import { useForm } from '@/hooks/web/useForm'
import { ElMessage } from 'element-plus'
const { push } = useRouter()
const { t } = useI18n()
const { required } = useValidator()
const { searchRegister, searchMethods } = useSearch()
const { getFormData } = searchMethods
const id = ref<string>()
const rules = reactive({
  pageName: [required()],
  formId: [required()]
})
const publishRules = reactive({
  title: [required()],
  parentMenuId: [required()],
  roles: [required()]
})
const { tableRegister, tableState, tableMethods } = useTable({
  fetchDataApi: async () => {
    const formData = await getFormData()
    const res = await selectPageApi({
      pageName: formData.pageName,
      page: { size: unref(pageSize), current: unref(currentPage) }
    })
    return {
      list: res.result.records || [],
      total: res.result.total
    }
  },
  fetchDelApi: async () => {
    const res = await deleteDataApi({ id: id.value })
    return !!res
  }
})
const { dataList, loading, total, currentPage, pageSize } = tableState

const { getList, refresh, delList } = tableMethods

const tableColumns = reactive<TableColumn[]>([
  {
    field: 'index',
    label: t('userDemo.index'),
    type: 'index'
  },
  {
    field: 'pageName',
    label: '页面名称'
  },
  {
    field: 'modelId',
    label: '模型id'
  },
  {
    field: 'formId',
    label: '表单id'
  },
  {
    field: 'version',
    label: '版本'
  },
  {
    field: 'createBy',
    label: '创建人'
  },
  {
    field: 'createTime',
    label: '创建日期'
  },
  {
    field: 'updateBy',
    label: '更新人'
  },
  {
    field: 'updateTime',
    label: '更新时间'
  },
  {
    field: 'action',
    label: t('userDemo.action'),
    width: 310,
    slots: {
      default: (data: any) => {
        const row = data.row
        return (
          <>
            <BaseButton type="primary" onClick={() => edit(row, 'edit')}>
              {t('exampleDemo.edit')}
            </BaseButton>
            <BaseButton type="success" onClick={() => preview(row)}>
              预览
            </BaseButton>
            <BaseButton type="warning" onClick={() => publish(row)}>
              发布
            </BaseButton>
            <BaseButton type="danger" onClick={() => delData(row)}>
              {t('exampleDemo.del')}
            </BaseButton>
          </>
        )
      }
    }
  }
])
nextTick(() => {
  remoteMethod('')
})
const delLoading = ref(false)
const delData = async (row) => {
  id.value = row.id || ''
  delLoading.value = true
  await delList(1).finally(() => {
    delLoading.value = false
  })
}
const searchSchema = reactive<FormSchema[]>([
  {
    field: 'pageName',
    label: '页面名称',
    component: 'Input'
  }
])
const searchParams = ref({})
const setSearchParams = (data: any) => {
  searchParams.value = data
  getList()
}

const dialogVisible = ref(false)
const dialogTitle = ref('')

const currentRow = ref()
const actionType = ref('')
const { formRegister, formMethods } = useForm()
const active = ref(0)
const saveLoading = ref(false)
const form = ref({
  pageName: '',
  formId: '',
  queryField: [],
  showField: []
})
const publishVisible = ref(false)
const publish = (row: any) => {
  dialogTitle.value = '发布部署'
  currentRow.value = row
  publishVisible.value = true
}
const edit = (row: any, type: string) => {
  dialogTitle.value = t(type === 'edit' ? 'exampleDemo.edit' : 'exampleDemo.detail')
  actionType.value = type
  console.log('row', row)
  active.value = 0
  form.value = row
  if (!Array.isArray(row.queryField)) {
    form.value.queryField =
      row.queryField && row.queryField.length > 0 ? row.queryField.split(',') : []
  }
  if (!Array.isArray(row.showField)) {
    form.value.showField = row.showField && row.showField.length > 0 ? row.showField.split(',') : []
  }
  remoteMethod('')
  generateData()
  dialogVisible.value = true
}
const AddAction = () => {
  dialogTitle.value = t('exampleDemo.add')
  currentRow.value = undefined
  dialogVisible.value = true
  actionType.value = ''
  form.value = {
    pageName: '',
    formId: '',
    queryField: [],
    showField: []
  }
  remoteMethod('')
}
const selectLoading = ref(false)
const selectOptions = ref([])
const remoteMethod = async (query) => {
  selectLoading.value = true
  const res = await getFormOptionsApi({ formName: query })
  if (res.success) {
    selectOptions.value = res.result
    selectLoading.value = false
  }
}
const formRef = ref(null)
const next = async () => {
  formRef.value.validate((valid) => {
    if (valid) {
      if (active.value < 2) {
        active.value++
      } else {
        console.log('formData', form)
        saveData()

        // generateData()
        // push({
        //   path: '/lowCode/pageConfig',
        //   query: {}
        // })
      }
    } else {
      console.log('error submit!')
    }
  })
}
const preview = (row) => {
  push({
    path: '/lowCode/pageConfig',
    query: { pageId: row.id }
  })
}
const saveData = async () => {
  saveLoading.value = true
  const formData = form.value
  formData.showField = form.value.showField.join(',')
  formData.queryField = form.value.queryField.join(',')
  const res =
    actionType.value !== 'edit' ? await saveDataApi(formData) : await updateDataApi(formData)
  if (res.success) {
    dialogVisible.value = false
  }
  saveLoading.value = false
  getList()
}
const last = () => {
  if (active.value != 0) {
    active.value--
  }
}
interface Option {
  key: number
  label: string
  initial: string
}
const selectChange = () => {
  generateData()
}
const data = ref<Option[]>()
const generateData = async () => {
  const data1: Option[] = []
  if (form.value.formId) {
    const res = await selectModelByFormIdApi({ id: form.value.formId })
    if (res.success) {
      res.result.fieldList.forEach((item) => {
        data1.push({
          label: item.remarks,
          key: item.fieldName,
          initial: item.remarks
        })
      })
    }
  }
  data.value = data1
  return data1
}

const formSchema = reactive<FormSchema[]>([
  {
    field: 'title',
    label: t('menu.menuName'),
    component: 'Input'
  },
  {
    field: 'parentMenuId',
    label: '父级菜单',
    component: 'TreeSelect',
    componentProps: {
      nodeKey: 'id',
      props: {
        label: 'title',
        value: 'id',
        children: 'children'
      },
      highlightCurrent: true,
      expandOnClickNode: false,
      checkStrictly: true,
      checkOnClickNode: true,
      clearable: true
    },
    optionApi: async () => {
      const res = await getMenuListApi('')
      return res.result || []
    }
  },
  {
    field: 'roles',
    label: t('userDemo.role'),
    component: 'Select',
    value: [],
    componentProps: {
      multiple: true,
      collapseTags: true,
      maxCollapseTags: 1
    },
    optionApi: async () => {
      const res = await getRoleListApi({})
      return res.result?.map((v) => ({
        label: v.roleName,
        value: v.roleCode
      }))
    }
  }
])

const filterMethod = (query, item) => {
  return item.initial.toLowerCase().includes(query.toLowerCase())
}

const publishSave = async () => {
  const formData = await formMethods.getFormData()
  formData.pageId = currentRow.value.id
  const res = await publishApi(formData)
  if (res.success) {
    publishVisible.value = false
    ElMessage.success(res.message)
  }
}
</script>

<template>
  <ContentWrap>
    <Search
      :schema="searchSchema"
      @reset="setSearchParams"
      @search="setSearchParams"
      @register="searchRegister"
    />
    <div class="mb-10px">
      <BaseButton type="primary" @click="AddAction">{{ t('exampleDemo.add') }}</BaseButton>
    </div>
    <Table
      v-model:pageSize="pageSize"
      v-model:currentPage="currentPage"
      @refresh="refresh"
      :columns="tableColumns"
      default-expand-all
      node-key="id"
      :data="dataList"
      :loading="loading"
      :pagination="{
        total
      }"
      @register="tableRegister"
    />
  </ContentWrap>
  <Dialog v-model="publishVisible" :title="dialogTitle" maxHeight="100px">
    <Form :rules="publishRules" @register="formRegister" :schema="formSchema" />
    <template #footer>
      <BaseButton type="primary" :loading="saveLoading" @click="publishSave"> 发布 </BaseButton>

      <BaseButton @click="publishVisible = false">{{ t('dialogDemo.close') }}</BaseButton>
    </template>
  </Dialog>

  <Dialog v-model="dialogVisible" :title="dialogTitle">
    <el-steps
      :space="300"
      :active="active"
      finish-status="success"
      process-status="finish"
      align-center
    >
      <el-step title="基本信息" />
      <el-step title="查询字段" />
      <el-step title="展示字段" />
    </el-steps>
    <el-form :model="form" label-width="auto" :rules="rules" ref="formRef">
      <div v-if="active === 0">
        <el-form-item label="页面名称" prop="pageName">
          <el-input v-model="form.pageName" placeholder="如:订单管理、收支报表" />
        </el-form-item>
        <el-form-item label="关联表单" prop="formId">
          <el-select
            v-model="form.formId"
            placeholder="请选择关联表单"
            :remote="true"
            :loading="selectLoading"
            filterable
            :remote-method="remoteMethod"
            @change="selectChange"
          >
            <el-option
              v-for="item in selectOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
      </div>
      <div v-if="active === 1">
        <div style="text-align: center">
          <el-transfer
            v-model="form.queryField"
            filterable
            :filter-method="filterMethod"
            :titles="['模型字段', '查询字段']"
            filter-placeholder="字段搜索"
            :data="data"
          />
        </div>
      </div>
      <div v-if="active === 2">
        <div style="text-align: center">
          <el-transfer
            v-model="form.showField"
            filterable
            :filter-method="filterMethod"
            :titles="['模型字段', '展示字段']"
            filter-placeholder="字段搜索"
            :data="data"
          />
        </div>
      </div>
    </el-form>
    <template #footer>
      <BaseButton :loading="saveLoading" @click="last"> 上一步 </BaseButton>
      <BaseButton type="primary" :loading="saveLoading" @click="next">
        {{ active === 2 ? '创建' : '下一步' }}
      </BaseButton>
      <BaseButton @click="dialogVisible = false">{{ t('dialogDemo.close') }}</BaseButton>
    </template>
  </Dialog>
</template>
